#ifndef KV_NET_SOCKET_H
#define KV_NET_SOCKET_H

#include "nr_std.h"
#include <QtNetwork/QTcpSocket>

class nr_net_socket : public QObject
{
    Q_OBJECT
public:
    nr_net_socket(QTcpSocket *socket) 
        : QObject(socket->parent())
        , m_tcp_socket(socket) 
        , m_data(NULL)
    {
        bool ret = connect(m_tcp_socket, SIGNAL(readyRead()), this, SLOT(read_data())); 
        Q_ASSERT(ret);
        
        ret = connect(m_tcp_socket, SIGNAL(connected()), this, SLOT(socket_connected())) ;
        Q_ASSERT(ret);

        ret = connect(m_tcp_socket, SIGNAL(aboutToClose()), this, SLOT(about_to_close())); 
        Q_ASSERT(ret);

        ret = connect(m_tcp_socket, SIGNAL(disconnected()), this, SLOT(about_disconneted())); 
        Q_ASSERT(ret);

        ret = connect(m_tcp_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(about_error(QAbstractSocket::SocketError))); 
        Q_ASSERT(ret);

        m_session_id = g_session_id++;
    }

    virtual ~nr_net_socket(void) { delete m_tcp_socket; }

    QTcpSocket *socket() { return m_tcp_socket; }

    void*& data() { return m_data; } 

    nr_id_t& session_id() { return m_session_id; }
    
    QString& cookie() { return m_cookie; }
    
signals:
    void net_ready_read(nr_net_socket* socket);
    void net_about_to_close(nr_net_socket* socket);
    void net_connected(nr_net_socket* socket);
    void net_error(nr_net_socket* socket);

private:
    QTcpSocket *m_tcp_socket;
    void *m_data;
    nr_id_t m_session_id;
    QString m_cookie;

    static nr_id_t g_session_id;

private slots:
    void socket_connected() { emit net_connected(this); }
    void read_data() { emit net_ready_read(this); }
    void about_to_close() { emit net_about_to_close(this); }
    void about_disconneted() { m_tcp_socket->close(); }
    void about_error(QAbstractSocket::SocketError) { emit net_error(this); }
};

#endif